<script setup lang="ts">
import UserRequest from '@/request/userRequest';
import userRequest from '@/request/userRequest';
import Location from '@/utils/location';
import validate, { IValidator } from '@/utils/validate';
import useToast from '@/hooks/useToast';
import to from '@/utils/to';
import { navigate } from '@/utils/navigate';
import useModal from '@/hooks/useModal';
import Tools from '@/utils/tools';
import eventBus from '@/utils/eventBus';

interface IState {
  villagePickerShow: boolean;
  villageList: IResidentialAddressListRes[];
  cascaderShow: boolean;
  cascaderValue: string;
  cascaderData: IBuildingTreeRes[];
  cascaderOptions: IBuildingTreeRes[];
  cascaderSelectedOptions: IBuildingTreeRes[];
  beeperId?: number;
  relationBeeperId?: number;
  harvestAddressId?: number;
  variantIds?: string;
  formData: {
    villageId?: number;
    houseNumber?: string;
    location?: { [key: string]: string };
    linkName: string;
    phone: string;
    [key: string]: any;
  };
}

const state = reactive<IState>({ villagePickerShow: false, cascaderShow: false, cascaderSelectedOptions: [], cascaderOptions: [], cascaderData: [], cascaderValue: '', villageList: [], formData: { linkName: '', phone: '' } });
const { showToast } = useToast();
const { showModal } = useModal();
const validators: IValidator<typeof state.formData>[] = [
  { key: 'houseNumber', name: '详细地址', required: true },
  { key: 'phone', name: '联系人电话', required: true, rule: /^(?:\+86)?1[3-9]\d{9}$/ },
  { key: 'linkName', name: '联系人', required: true },
];

onLoad((options) => {
  if (!options) return;
  if (options.relationBeeperId) state.relationBeeperId = options.relationBeeperId;
  if (options.beeperId) state.beeperId = options.beeperId;
  if (options.variantIds) state.variantIds = options.variantIds; // 变体ids 从下单界面来的
  if (options.harvestAddressId) fetchAddressDetails(Number(options.harvestAddressId));
});

// 根据id获取地址详情
const fetchAddressDetails = (id: number) => {
  state.harvestAddressId = id;
  UserRequest.GetAddressDetails({ id, hasLoading: true }).then((res) => {
    const { address, provinceName, cityName, areaName, streetName, latitude, longitude, linkName, phone, villageId, buildId, buildName, unitId, unitName, floorId, floorName, houseNumberId, houseNumber } = res.data;
    state.formData.location = { provinceName, cityName, areaName, streetName, latitude: latitude.toString(), longitude: longitude.toString(), address };
    state.formData.linkName = linkName;
    state.formData.phone = phone;
    state.formData.houseNumber = houseNumber;
    if (state.beeperId || state.relationBeeperId) {
      state.formData.villageId = villageId;
      if (buildId) {
        state.cascaderSelectedOptions.push({ id: String(buildId), name: buildName, parentId: 0, levels: 1, children: [] });
        state.cascaderValue = String(buildId);
      }
      if (unitId) {
        state.cascaderSelectedOptions.push({ id: String(unitId), name: unitName, parentId: 0, levels: 1, children: [] });
        state.cascaderValue = String(unitId);
      }
      if (floorId) {
        state.cascaderSelectedOptions.push({ id: String(floorId), name: floorName, parentId: 0, levels: 1, children: [] });
        state.cascaderValue = String(floorId);
      }
      if (houseNumberId) {
        state.cascaderSelectedOptions.push({ id: String(houseNumberId), name: houseNumber, parentId: 0, levels: 1, children: [] });
        state.cascaderValue = String(houseNumberId);
      }
      fetchResidentialAddressList();
      if (villageId) fetchBuildingTree(villageId);
    }
  });
};

// 打开地图选取地址
const handleChooseLocation = async () => {
  let position = {};
  if (state.formData.location && state.formData.location.longitude && state.formData.location.latitude) {
    position = { latitude: state.formData.location.latitude, longitude: state.formData.location.longitude };
  }
  const chooseRes = await uni.chooseLocation(position);
  if (!chooseRes) return;
  const location = await Location.reverseGeocoderLocation({ lat: chooseRes.latitude, lng: chooseRes.longitude });
  if (!location) return;
  const { address_component, formatted_addresses } = location;
  state.formData.location = {
    provinceName: address_component.province,
    cityName: address_component.city,
    areaName: address_component.district,
    streetName: address_component.street,
    latitude: chooseRes.latitude.toString(),
    longitude: chooseRes.longitude.toString(),
    address: formatted_addresses.recommend,
  };
  if (state.beeperId || state.relationBeeperId) {
    state.cascaderValue = '';
    state.cascaderData = [];
    state.cascaderOptions = [];
    delete state.formData.villageId;
    fetchResidentialAddressList();
  }
};

// 获取小区列表数据
const fetchResidentialAddressList = () => {
  UserRequest.ResidentialAddressList({ ...state.formData.location, hasLoading: true }).then((res) => {
    state.villageList = res.data;
    if (!state.villageList.some((item) => item.id === state.formData.villageId)) {
      delete state.formData.villageId;
    }
  });
};

// 获取小区楼栋层数据
const fetchBuildingTree = (villageId: number) => {
  userRequest.BuildingTree({ villageId }).then((res) => {
    state.cascaderData = res.data;
    state.cascaderOptions = Tools.deEmptyChildrenCascader(res.data).map((item) => {
      if (state.cascaderValue && item.id === state.cascaderSelectedOptions[0].id) {
        return item;
      } else {
        return { ...item, children: [] };
      }
    });
  });
};

// 小区选择器选中事件
const handleVillagePickerConfirm = (e: any) => {
  state.formData.villageId = e.detail.value.id;
  state.villagePickerShow = false;
  state.cascaderValue = '';
  state.cascaderOptions = [];
  fetchBuildingTree(Number(state.formData.villageId));
};

// 楼栋层选择器选中事件
const handleCascaderChange = (e: any) => {
  const { tabIndex, selectedOptions, value } = e.detail;
  const insertData = Tools.findPathDFS<IBuildingTreeRes>(state.cascaderData, e.detail.value);
  if (!insertData) return;
  const index = state.cascaderData.findIndex((item) => item.id === insertData.id);
  state.cascaderValue = value;
  state.cascaderSelectedOptions = selectedOptions;
  if (tabIndex === 0) {
    state.cascaderOptions = Tools.deEmptyChildrenCascader(state.cascaderData).map((item) => {
      return { ...item, children: [] };
    });
    state.cascaderOptions[index].children = insertData.children;
  }
};

// 楼栋层选择器选择完成事件
const handleCascaderFinish = (e: any) => {
  const { selectedOptions, value } = e.detail;
  state.cascaderSelectedOptions = selectedOptions;
  state.cascaderValue = value;
  state.cascaderShow = false;
};

// 保存地址
const handleSaveAddress = async (keepUp: number = 0) => {
  if (!state.harvestAddressId && !state.formData.location) {
    validators.push({ key: 'location', name: '收货地址', required: true, requiredMsg: '请选择收货地址' });
  }
  const isValid = validate(state.formData, validators);
  if (!isValid) return;
  const params: any = { ...state.formData, ...state.formData.location, hasLoading: true };
  if (state.beeperId || state.relationBeeperId) {
    if (!params.address) {
      showToast('请完善地址信息');
      return;
    }
    if (!state.cascaderValue) {
      showToast('请选择详细地址');
      return;
    }
    validators.push({ key: 'villageId', name: '小区', required: true });
    if (state.cascaderSelectedOptions.length > 0) {
      params.buildId = state.cascaderSelectedOptions[0].id;
      params.buildName = state.cascaderSelectedOptions[0].name;
    }
    if (state.cascaderSelectedOptions.length > 1) {
      params.unitId = state.cascaderSelectedOptions[1].id;
      params.unitName = state.cascaderSelectedOptions[1].name;
    }
    if (state.cascaderSelectedOptions.length > 2) {
      params.floorId = state.cascaderSelectedOptions[2].id;
      params.floorName = state.cascaderSelectedOptions[2].name;
    }
    if (state.cascaderSelectedOptions.length > 3) {
      params.houseNumberId = state.cascaderSelectedOptions[3].id;
      params.houseNumber = state.cascaderSelectedOptions[3].name;
    }
  }
  if (state.variantIds) {
    params.variantIds = state.variantIds;
    params.keepUp = keepUp;
  }
  delete params.location;
  const [err, res] = await to(state.harvestAddressId ? UserRequest.EditShippingAddress({ ...params, harvestAddressId: state.harvestAddressId }) : UserRequest.SaveShippingAddress(params));
  if (err) return;
  if (res.data === 0) {
    showModal('您的地址超出商家的配送范围了', { showCancel: true, confirmText: '仍然保存', cancelText: '调整地址' }).then(async (res) => {
      if (res.confirm) await handleSaveAddress(1);
    });
  } else {
    showToast('保存地址成功').then(() => {
      if (params.variantIds) eventBus.emit('callHarvestAddress', res.data);
      setTimeout(() => {
        navigate({ url: '', type: 'navigateBack' });
      }, 500);
    });
  }
};

// 删除地址
const handleDeleteAddress = () => {
  showModal('地址删除后无法恢复，是否删除地址？', { showCancel: true }).then((res) => {
    if (res.confirm) {
      UserRequest.DeleteShippingAddress({ id: state.harvestAddressId, state: -1 }).then((res) => {
        showToast('删除地址成功').then(() => {
          if (state.variantIds) eventBus.emit('callHarvestAddress', undefined);
          setTimeout(() => {
            navigate({ url: '', type: 'navigateBack' });
          }, 500);
        });
      });
    }
  });
};
</script>

<template>
  <map class="w-screen h-screen" :longitude="state.formData.location ? Number(state.formData.location.longitude) : 116.397517" :latitude="state.formData.location ? Number(state.formData.location.latitude) : 39.908245" :enable-zoom="false" :enable-scroll="false" />
  <view class="c-pd w-screen h-screen pos-absolute top-0 left-0 pt-30%">
    <view class="bg-white c-br c-pd c-pd mb-12px flex justify-between items-center">
      <template v-if="state.formData.location">
        <view class="flex-1 mr-12px" v-if="state.formData.location">
          <view class="fw-bold">{{ state.formData.location.address }}</view>
          <view class="c-text-color-grey c-text-12">{{ state.formData.location.provinceName + state.formData.location.cityName + state.formData.location.areaName + state.formData.location.streetName }}</view>
        </view>
        <view class="w-100px" @click="handleChooseLocation">
          <van-button type="primary" plain block size="small"> {{ state.formData.location.address ? '修改地址' : '完善地址' }} </van-button>
        </view>
      </template>
      <view class="w-full" v-if="!state.harvestAddressId && !state.formData.location" @click="handleChooseLocation">
        <van-button type="primary" plain block> 选择收货地址 </van-button>
      </view>
    </view>
    <view class="bg-white c-br c-pd c-pd">
      <template v-if="state.beeperId || state.relationBeeperId">
        <van-cell title="小区" required is-link @click="state.villagePickerShow = true">
          <view class="c-text-color-grey text-align-left" v-if="!state.formData.villageId || state.villageList.length === 0">请选择小区</view>
          <view class="c-color-black text-align-left" v-else>{{ state.villageList.find((item) => item.id === state.formData.villageId)?.name || '' }}</view>
        </van-cell>
        <van-cell title="详细地址" required is-link @click="state.cascaderShow = true">
          <view class="c-text-color-grey text-align-left" v-if="!state.cascaderValue">请选择详细地址</view>
          <view class="c-color-black text-align-left" v-else>{{ state.cascaderSelectedOptions.map((item: IBuildingTreeRes) => item.name).join('-') }}</view>
        </van-cell>
      </template>
      <van-field v-else clearable clickable :value="state.formData.houseNumber" label="详细地址" placeholder="请输入详细地址，例1栋301室" required @change="state.formData.houseNumber = $event.detail" />
      <van-field clearable clickable :value="state.formData.linkName" label="联系人" placeholder="请输入联系人" required @change="state.formData.linkName = $event.detail" />
      <van-field clearable clickable :value="state.formData.phone" label="电话" placeholder="请输入联系人电话" required @change="state.formData.phone = $event.detail" />
    </view>
    <view class="mt-12px">
      <van-button type="primary" :color="'#ffc300'" block @click="handleSaveAddress(0)"> 保存地址 </van-button>
    </view>
    <view class="mt-12px" v-if="!state.beeperId && !state.relationBeeperId && state.harvestAddressId" @click="handleDeleteAddress">
      <van-button type="primary" plain block> 删除地址 </van-button>
    </view>
  </view>

  <van-popup position="bottom" round :show="state.villagePickerShow" @close="state.villagePickerShow = false">
    <view class="bg-white w-full">
      <van-picker v-if="state.villageList.length > 0" show-toolbar value-key="name" :columns="state.villageList" :title="`请选择小区`" @cancel="state.villagePickerShow = false" @confirm="handleVillagePickerConfirm" />
      <van-empty description="该地址下没有小区信息" v-else />
    </view>
  </van-popup>
  <van-popup :show="state.cascaderShow" round position="bottom" @close="state.cascaderShow = false">
    <van-cascader
      v-if="state.cascaderOptions.length > 0"
      :active-color="'#ffc300'"
      :show="state.cascaderShow"
      :value="state.cascaderValue"
      :field-names="{ text: 'name', value: 'id' }"
      title="请选择详细地址"
      :options="state.cascaderOptions"
      @close="state.cascaderShow = false"
      @change="handleCascaderChange"
      @finish="handleCascaderFinish"
    />
    <van-empty description="该小区下没有楼栋层信息" v-else />
  </van-popup>
</template>

<style lang="scss" scoped>
:deep(.van-cell__title) {
  margin-right: 12px !important;
  min-width: 72px !important;
  max-width: 72px !important;
}
</style>
